
#include "stm32f10x.h"
#include "delay.h"
#include "sys.h"

u8 _viewdata_array[8];

const u8 _address_array[8][2] =
{
    {0x01, 0x02}, {0x03, 0x04}, {0x05, 0x06}, {0x07, 0x08}, //
    {0x09, 0x0A}, {0x0B, 0x0C}, {0x0D, 0x0E}, {0x0F, 0x10} //
};

const u8 _number_array[50][2] =
{
    {0x0d, 0x0f},//0
    {0x00, 0x0e},//1
    {0x0e, 0x0b},//2
    {0x0a, 0x0f},//3
    {0x03, 0x0e},//4
    {0x0b, 0x0d},//5
    {0x0f, 0x0d},//6
    {0x00, 0x0f},//7
    {0x0f, 0x0f},//8
    {0x0b, 0x0f},//9
    {0x00, 0x00},//10.不显示
    {0x02, 0x00},//11.负号,减号
    {0x0d, 0x00},//12.大写L
    {0x0e, 0x04},//13.小写O，下半区全显示
    {0x0f, 0x01},//14.大写E，反写的3
    {0x06, 0x00},//15.下半区反写的7，好象用处不大
    {0x07, 0x06},//16.大写H
    {0x0c, 0x04},//17.下半区，口朝上框
    {0x06, 0x04} //18.下半区，口朝下框
};

#define DataHigh()  GPIO_WriteBit(GPIOA, GPIO_Pin_3, Bit_SET);
#define DataLow()   GPIO_WriteBit(GPIOA, GPIO_Pin_3, Bit_RESET);
#define WRHigh()    GPIO_WriteBit(GPIOA, GPIO_Pin_2, Bit_SET);
#define WRLow()     GPIO_WriteBit(GPIOA, GPIO_Pin_2, Bit_RESET);
#define CSHigh()    GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_SET);
#define CSLow()     GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_RESET);

void pslcd_lock_address(u8 address)
{
    u8 i;
    for (i = 0; i < 3; i++)
    {
        if (address & 0x80)
        {
            DataHigh();
        }
        else
        {
            DataLow();
        }
        WRLow();
        WRHigh();
        address = address << 1;
    }
}

void pslcd_write_command(u8 command)
{
    u8 i;
    CSLow();
    for (i = 0; i < 8; i++)
    {
        if (command & 0x80)
        {
            DataHigh();
        }
        else
        {
            DataLow();
        }
        WRLow();
        WRHigh();
        command = command << 1;
    }
    DataLow();
    WRLow();
    WRHigh();
    CSHigh();
}

void pslcd_write_data(u8 address, u8 viewData)
{
    u8 i;
    CSLow();
    pslcd_lock_address(0xa0);
    address = address << 2;
    for (i = 0; i < 6; i++)
    {
        if (address & 0x80)
        {
            DataHigh();
        }
        else
        {
            DataLow();
        }
        WRLow();
        WRHigh();
        address = address << 1;
    }
    viewData = viewData << 4;
    for (i = 0; i < 4; i++)
    {
        if (viewData & 0x80)
        {
            DataHigh();
        }
        else
        {
            DataLow();
        }
        WRLow();
        WRHigh();
        viewData = viewData << 1;
    }
    CSHigh();
}

void pslcd_reset(void)
{
    CSLow();
    pslcd_lock_address(0x80);
    pslcd_write_command(0x01); //SYS EN: Trun on system oscillator
    pslcd_write_command(0x29); //BIAS 1/3, 4com
    pslcd_write_command(0x03); //LCD ON: Turn on LCD bias generator
    CSHigh();
}

void pslcd_initialize(void)
{
    GPIO_InitTypeDef def;

    def.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
    def.GPIO_Mode = GPIO_Mode_Out_PP;
    def.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &def);

    Delay_Ms(1);
    pslcd_reset();
    Delay_Ms(1);
    pslcd_write_data(0, 0x00);
    pslcd_write_data(17, 0x00);
}

void pslcd_display(u8 position, u8 number)
{
    if (_viewdata_array[position] == number)
        return;
    else
        _viewdata_array[position] = number;

    pslcd_write_data(_address_array[position][0], _number_array[number][0]);
    pslcd_write_data(_address_array[position][1], _number_array[number][1]);
}

void pslcd_display_blank(u8 position)
{
    pslcd_display(position, 10);
}

void pslcd_display_minus(u8 position)
{
    pslcd_display(position, 11);
}

void pslcd_clear()
{
    u8 i;
    for (i = 0; i <= 7; i++)
    {
        pslcd_display_blank(i);
    }
}

void pslcd_display_integer(long integer)
{
    if (integer > 99999)
        return;
    pslcd_display(0, integer / 10000); //转换为字符显示
    pslcd_display(1, integer % 10000 / 1000);
    pslcd_display(2, integer % 1000 / 100);
    pslcd_display(3, integer % 100 / 10);
    pslcd_display(4, integer % 10);
    pslcd_display_blank(5);
    pslcd_display_blank(6);
    pslcd_display_blank(7);
}

void pslcd_display_float(float floatNumber)
{
    signed long integer = floatNumber * 1000;
    if (integer > 99999999)
        return;
    pslcd_display(0, integer / 10000000);  //转换为字符显示
    pslcd_display(1, integer % 10000000 / 1000000);
    pslcd_display(2, integer % 1000000 / 100000);
    pslcd_display(3, integer % 100000 / 10000);
    pslcd_display(4, integer % 10000 / 1000);
    pslcd_display(5, integer % 1000 / 100);
    pslcd_display(6, integer % 100 / 10);
    pslcd_display(7, integer % 10);
}

void pslcd_demo_display()
{
    pslcd_display(0, 1);
    pslcd_display(1, 2);
    pslcd_display(2, 3);
    pslcd_display(3, 4);
    pslcd_display(4, 5);
    pslcd_display(5, 9);
    pslcd_display(6, 8);
    pslcd_display(7, 7);
}

int main(void)
{
    u32 i;
    int integer = 0;
    float number = 10000.000;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    pslcd_initialize();

    for (i = 0; i < 3; i++)
    {
        pslcd_clear();
        Delay_Ms(200);
        pslcd_display_float(88888.888);
        Delay_Ms(800);
    }

    for (i = 0; i < 10; i++)
    {
        pslcd_display_integer(integer);
        integer += 11111;
        Delay_Ms(500);
    }

    pslcd_display_float(54321.666);
    Delay_Ms(300);
    pslcd_display_float(12345.777);
    Delay_Ms(300);
    pslcd_display_float(12345.888);
    Delay_Ms(300);
    pslcd_display_float(99999.999);
    Delay_Ms(1000);

    while (1)
    {
        number = 0.001;
        for (i = 0; i < 99999; i++)
        {
            number += 1.001;
            pslcd_display_float(number);
        }
        Delay_Ms(5000);
    }
}


#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
    /* User can add his own implementation to report the file name and line number,
       ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

    /* Infinite loop */
    while (1)
    {
    }
}
#endif
